package com.example.d1116_video.slice;

import com.example.d1116_video.DateUtils;
import com.example.d1116_video.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Slider;
import ohos.agp.components.Text;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.window.dialog.ToastDialog;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.common.Source;
import ohos.media.player.Player;

import java.text.DecimalFormat;
import java.util.Optional;


public class MainAbilitySlice extends AbilitySlice {


    private static final HiLogLabel LABEL_LOG = new HiLogLabel(0, 0, "MY_LOG");

    /**
     * 播放对象
     */
    private Player mPlayer;

    /**
     * 播放窗口提供者
     */
    private SurfaceProvider mPlayWindowProvider;


    /**
     * 负责进度更新的handler
     */
    private ControllerHandler mHandler;
    /**
     * 更新播放进度的事件
     */
    public static final int PLAYER_PROGRESS_RUNNING = 0;
    /**
     * 进度更新周期 1s
     */
    public static final int PROGRESS_RUNNING_TIME = 1000;


    /**
     * 播放窗口
     */
    private Surface mPlayWindow;

    /**
     * 音量
     */
    private Slider mVolumeSlider;

    /**
     * 进度
     */
    private Slider mProgressSlider;


    private Text mCurrentVolume;        //当前音量
    private Text mCurrentProgress;    //当前进度
    private Text mMaxProgress;       //最大进度

    private Button mPusBtn;   // 暂停


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);

        initComponent();
        initWindow();
        initPlayer();
        initHandler();

    }

    /**
     * 初始化一个控制播放进度的handler
     */
    private void initHandler() {
        EventRunner runner = EventRunner.create(true);
        if (runner == null) {
            return;
        }
        mHandler = new ControllerHandler(runner);
    }


    private void initPlayer() {

        mPlayer = new Player(getContext());

        mPlayer.setPlayerCallback(new Player.IPlayerCallback() {
            @Override
            public void onPrepared() {

            }

            @Override
            public void onMessage(int i, int i1) {
                //播放器返回一些消息，type：消息类型   extra：不同消息类型给对应的数据
                //type：对应 Player中的PLAYER_xxxx类型
            }

            @Override
            public void onError(int i, int i1) {
                //播放错误，type：错误类型   errorCode：错误码
                //type和errorCode：对应 Player中的PLAYER_ERROR类型
            }

            @Override
            public void onResolutionChanged(int i, int i1) {
                //播放窗口大小变化
            }

            @Override
            public void onPlayBackComplete() {
                //播放完成

                mHandler.removeEvent(PLAYER_PROGRESS_RUNNING);

            }

            @Override
            public void onRewindToComplete() {
                //调用 Player.rewindTo(long)改变播放进度. 方法会触发该方法


            }

            @Override
            public void onBufferingChange(int i) {
                //缓冲百分比变化

            }

            @Override
            public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) {
                //有新的可播放数据时触发

            }

            @Override
            public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {

                //当媒体时间连续性被打破时调用
                //例如：当播放过程中发生错误时、播放位置被Player.rewindTo(long)改变、或播放速度突然改变。
            }
        });


    }


    private void initWindow() {
        mPlayWindowProvider = findComponentById(ResourceTable.Id_sur_main);

        Optional<SurfaceOps> surfaceOps = mPlayWindowProvider.getSurfaceOps();

        if (surfaceOps.isPresent()) {
            SurfaceOps ops = surfaceOps.get();

            ops.addCallback(new SurfaceOps.Callback() {
                @Override
                public void surfaceCreated(SurfaceOps surfaceOps) {
                    if (mPlayWindowProvider.getSurfaceOps().isPresent()) {
                        mPlayWindow = mPlayWindowProvider.getSurfaceOps().get().getSurface();
                    }

                }

                @Override
                public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {

                }

                @Override
                public void surfaceDestroyed(SurfaceOps surfaceOps) {

                }
            });
        }
        mPlayWindowProvider.pinToZTop(true);

    }

    private void initComponent() {

        findComponentById(ResourceTable.Id_play_btn)
                .setClickedListener(component -> playVideo());

        mPusBtn = findComponentById(ResourceTable.Id_mSuspend_btn);
        mPusBtn.setClickedListener(component -> pausePlayVideo());

        findComponentById(ResourceTable.Id_fast_btn)
                .setClickedListener(component -> mPlayer.rewindTo((mPlayer.getCurrentTime() + 5000) * 1000));
        findComponentById(ResourceTable.Id_back_btn)
                .setClickedListener(component -> mPlayer.rewindTo((mPlayer.getCurrentTime() - 5000) * 1000));

        mCurrentVolume = findComponentById(ResourceTable.Id_cur_volume);

        mCurrentProgress = findComponentById(ResourceTable.Id_cur_play_time);
        mMaxProgress = findComponentById(ResourceTable.Id_max_play_time);

        mVolumeSlider = findComponentById(ResourceTable.Id_volume_progress);
        mProgressSlider = findComponentById(ResourceTable.Id_play_progress);

        // 时间进度
        mProgressSlider.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int i, boolean b) {
                HiLog.info(LABEL_LOG, "播放进度变化 onProgressUpdated position:%s  isUpdated:%s", i, b);
            }

            @Override
            public void onTouchStart(Slider slider) {

            }

            @Override
            public void onTouchEnd(Slider slider) {
                if (mPlayer != null) {
                    int progress = slider.getProgress();
                    mPlayer.rewindTo(progress * 1000);
                }
            }
        });

//      音量进度
        mVolumeSlider.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int i, boolean b) {
                HiLog.info(LABEL_LOG, "播放音量变化 onProgressUpdated position:%s  isUpdated:%s", i, b);

                mCurrentVolume.setText("当前音量:" + i);
                changeVolume(i);
            }

            @Override
            public void onTouchStart(Slider slider) {

            }

            @Override
            public void onTouchEnd(Slider slider) {

            }
        });

    }

    /**
     * @param position 进度条当前进度
     */
    private void changeVolume(int position) {
        if (mPlayer != null) {
            //进度条的范围是0-100，转为0.0-1.0之间
            DecimalFormat df = new DecimalFormat("0.00");
            Float volume = Float.valueOf(df.format((float) position / 100));
            //设置音量，取值范围是 0.0 到 1.0,

            mPlayer.setVolume(volume);
        }
    }


    private void pausePlayVideo() {
        if (mPlayer.isNowPlaying() && mPlayer != null) {
            mPusBtn.setText("继续");

            mPlayer.pause();
            mHandler.removeEvent(PLAYER_PROGRESS_RUNNING, EventHandler.Priority.IMMEDIATE);
        } else {
            startPlay();
            mPusBtn.setText("暂停");
        }

//        if (mPlayer != null) {
//
//
//        }
//        mHandler.removeEvent(PLAYER_PROGRESS_RUNNING, EventHandler.Priority.IMMEDIATE);

    }


    private void playVideo() {
        stopPlay();
        Source source = new Source("https://ss0.bdstatic.com/-0U0bnSm1A5BphGlnYG/cae-legoup-video-target/93be3d88-9fc2-4fbd-bd14-833bca731ca7.mp4");
        //设置媒体来源
        mPlayer.setSource(source);
        //关联播放布局（载体）
        mPlayer.setVideoSurface(mPlayWindow);
        //准备（装载）
        boolean prepare = mPlayer.prepare();
        if (!prepare) {
            new ToastDialog(getContext()).setText("还未准备就绪，请重试").show();
            HiLog.info(LABEL_LOG, "还未准备就绪，请重试");

            return;
        }

        startPlay();
    }

    private void startPlay() {
        if (mPlayer != null) {

            if (mVolumeSlider != null) {
                changeVolume(mVolumeSlider.getProgress());
            }

            int duration = mPlayer.getDuration();
            if (mProgressSlider != null) {
                mProgressSlider.setMaxValue(duration);
            }

            if (mMaxProgress != null) {
                String text = DateUtils.msToString(duration);
                mMaxProgress.setText(text);
            }
            //播放
            mPlayer.play();
        }

        if (mHandler != null) {
            //启动handler 更新播放进度
            mHandler.sendEvent(PLAYER_PROGRESS_RUNNING, EventHandler.Priority.IMMEDIATE);
        }
    }


    /**
     * 停止播放
     */
    private void stopPlay() {
        if (mPlayer != null && mPlayer.isNowPlaying()) {
            mPlayer.stop();
        }
        mHandler.removeEvent(PLAYER_PROGRESS_RUNNING, EventHandler.Priority.IMMEDIATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        //释放播放器资源
        mPlayWindowProvider.removeFromWindow();
        mPlayWindowProvider = null;
        mPlayWindow = null;
        mPlayer.release();
    }

    /**
     * 接受handler事件，主要负责更新播放进度
     */
    private class ControllerHandler extends EventHandler {

        private ControllerHandler(EventRunner runner) {
            super(runner);
        }

        @Override
        public void processEvent(InnerEvent event) {
            super.processEvent(event);
            if (event == null) {
                return;
            }
            switch (event.eventId) {
                //播放进度更新
                case PLAYER_PROGRESS_RUNNING:
                    if (mPlayer != null && mPlayer.isNowPlaying()) {

                        getContext().getUITaskDispatcher().asyncDispatch(() -> {
                            int currentPosition = mPlayer.getCurrentTime();

                            mProgressSlider.setProgressValue(currentPosition);
                            mCurrentProgress.setText(DateUtils.msToString(currentPosition));
                        });
                        //每1s更新一次进度
                        mHandler.sendEvent(PLAYER_PROGRESS_RUNNING, PROGRESS_RUNNING_TIME, Priority.HIGH);
                    }
                    break;
                default:
                    break;
            }
        }
    }


}



